<?php 
namespace App\Http\Components;

use App\Http\Components\AppComponent;
use Illuminate\Http\Request;
use App\library\UtilFunction;
use App\library\Pingpp\Pingpp;
use App\library\Pingpp\Charge;
use App\library\Pingpp\Error\Base;

use App\Models\UserAccountModel;
use App\Models\AccountBillModel;
/**
* 
*/
class AccountComponent extends AppComponent{
	
    public static $errmsg = ''; 

	public function __construct(){
        parent::__construct();
	}

    private $def_extras = array(
        'alipay_wap'=>array(
            'success_url' => 'http://www.yourdomain.com/success',
            'cancel_url' => 'http://www.yourdomain.com/cancel'
            // 'success_url' => 'http://localhost/pingpp-php-master/two.html',
            // 'cancel_url' => 'http://www.yourdomain.com/cancel'
        ),
        'upmp_wap'=>array(
            'result_url' => 'http://www.yourdomain.com/result?code='
        ),
        'bfb_wap'=>array(
            'result_url' => 'http://www.yourdomain.com/result?code='
        ),
        'upacp_wap'=>array(
            'result_url' => 'http://www.yourdomain.com/result?code='
        ),
        'wx_pub'=>array(
            'open_id' => ''
        ),
        'wx_pub_qr'=>array(
            'product_id' => ''
        ),
    );

    /**
     * 获取ping++支付对象
     */
    public function pay($order_data){
        Pingpp::setApiKey('sk_live_yTOe1OKOivzDq10Ke9CuLWnL');

        if (empty($order_data['channel']) || empty($order_data['amount'])) {
            // exit();
        }
        $channel = strtolower($order_data['channel']);
        $amount = $order_data['amount'];
        $subject = $order_data['subject'];
        $body = $order_data['body'];
        $order_no = $order_data['order_no'];
        $extra = isset($order_data['extra'])?$order_data['extra']:array();
        $client_ip = $_SERVER["REMOTE_ADDR"];
        $app_id = 'app_4yvT449qv9aDC4yf';

        // $order_no = substr(md5(time()), 0, 12);
        // $order_no = $order_data['order_no'];

        //$extra 在使用某些渠道的时候，需要填入相应的参数，其它渠道则是 array() .具体见以下代码或者官网中的文档。其他渠道时可以传空值也可以不传。
        if (!$extra) {
            $extra = isset($this->def_extras[$channel])?$this->def_extras[$channel]:array();
        }

        switch ($channel) {
            case 'wx_pub':
                if (!isset($extra['open_id']) || !$extra['open_id']) {
                    #ecpt
                }
                break;
            case 'wx_pub_qr':
                if (!isset($extra['product_id']) || !$extra['product_id']) {
                    #ecpt
                }
                break;
            default:
                break;
        }

        $charge_data = array(
                    "subject"   => $subject,
                    "body"      => $body,
                    "amount"    => $amount,
                    "order_no"  => $order_no,
                    "currency"  => "cny",
                    "extra"     => $extra,
                    "channel"   => $channel,
                    "client_ip" => $client_ip,
                    "app"       => array("id" => $app_id)
                );
        try {
            $ch = Charge::create($charge_data);
            return $ch;
        } catch (Base $e) {
            header('Status: ' . $e->getHttpStatus());
            return ($e->getHttpBody());
        }
    }

    /**
     * 申请退款
     */
    public static function refund($ch_id,$amount){
        Pingpp::setApiKey('sk_live_yTOe1OKOivzDq10Ke9CuLWnL');
        $ch = Charge::retrieve($ch_id);
        $result = $ch->refunds->create(
            array(
                'amount' =>  ($amount*100),
                'description' => '申请退款'
            )
        );

        return $result;

    }

    public static function generate_order_no($type,$channel){
        $pay_type = array(
            'recharge'=>'R',
            'corps_recharge'=>'CR',
            'corps_withdrawal'=>'CW',
            'corps_temppay'=>'CT',
            'refund'=>'P',
            'transfer'=>'T',
            'withdrawal'=>'W',
        );
        $channel_type = array(
            'alipay'=>'ap',
            'wx'=>'wx',
            'dddpocket'=>'dd',
        );
        $order_no = '';
        // 第一位为支付类型
        if (isset($pay_type[$type])) {
            $order_no.= $pay_type[$type];
        }else{
            return false;
        }
        // 第二三位为支付方式
        if (isset($channel_type[$channel])) {
            $order_no.= $channel_type[$channel];
        }else{
            return false;
        }
        // 接下几位是时间
        $now = date('YmdHis',time());
        $order_no.= $now;

        $order_no.= str_pad(mt_rand(100,999), 3);
        return $order_no;
    }

    public static function check_pay_password($user_id, $pay_password){
        $pay_password = md5($pay_password);
        $user_account = UserAccountModel::where('user_id',$user_id)->first();
        if ($user_account) {
            if ($user_account->pay_password == $pay_password) {
                return $user_account->balance;
            }elseif(!$user_account->pay_password){
                return SELF::_json('0','请先设置支付密码');
            }else{
                return SELF::_json('0','支付密码错误');   
            }
        }else{
            return SELF::_json('0','转账失败');   
        }
    }
    /**
     * 转账、提现、充值后加入账单，并操作余额
     * 转账：及时到账，立即操作余额
     * 提现：操作余额，并提交申请到后台，申请失败返回原值，成功需要人工转账
     * 充值：提交订单后不操作余额，需要接受到确认收款通知才会更新余额
     */
    public static function bill($type,$new_bill){
        $pay_type = array(
            'recharge'=> 1,
            'corps_recharge'=> -1,
            'corps_withdrawal'=> 1,
            'refund'=> 1,
            'transfer'=> -1,
            'transfer_to'=> 1,
            'withdrawal'=> -1,
        );

        $save_type = array(
            'recharge'=>'recharge',
            'corps_recharge'=>'pay',
            'corps_withdrawal'=>'recharge',
            'refund'=>'refund',
            'transfer'=>'transfer',
            'transfer_to'=>'transfer',
            'withdrawal'=>'withdrawal',
        );

        $bill_time = date('Y-m-d H:i:s',time());
        if ($new_bill) {
            $accountBill = new AccountBillModel();
            $accountBill->user_id = $new_bill['user_id'];
            $accountBill->order_no = $new_bill['order_no'];
            $accountBill->channel = isset($new_bill['channel'])?$new_bill['channel']:'dddpocket';

            if (isset($pay_type[$type])) {
                $amount = $new_bill['amount'] * $pay_type[$type];
                $accountBill->amount = $amount;
                $accountBill->type = $save_type[$type];
            }else{
                Self::$errmsg = '类型错误：'.$type;
                return false;
            }
            
            $accountBill->subject = $new_bill['subject'];
            $accountBill->body = $new_bill['body']?$new_bill['body']:'';
            $accountBill->currency = isset($new_bill['currency'])?$new_bill['currency']:'ddc';
            $accountBill->client_ip = UtilFunction::get_ip();
            if ($new_bill['channel'] == 'transfer') {
                $accountBill->status = 'succeeded';
            }else{
                $accountBill->status = isset($new_bill['status'])?$new_bill['status']:'created';
            }
            $accountBill->bill_time = $bill_time;
            if($accountBill->saveOrFail()){
                if ($type == 'transfer') {
                    // 转账及时到账，立即操作余额
                    $userAccount = UserAccountModel::where('user_id',$new_bill['user_id'])->first();
                    $userAccount->balance = $userAccount->balance + $amount;
                    $userAccount->saveOrFail();

                    // 操作被转账者账户
                    $accountBill = new AccountBillModel();
                    $accountBill->user_id = $new_bill['to_user_id'];
                    $accountBill->order_no = $new_bill['order_no'];
                    $accountBill->channel = isset($new_bill['channel'])?$new_bill['channel']:'dddpocket';

                    $amount = $new_bill['amount'] * $pay_type['transfer_to'];
                    $accountBill->type = $type;
                    $accountBill->amount = $amount;

                    $accountBill->subject = '转账收款';
                    $accountBill->body = $new_bill['body']?$new_bill['body']:'';
                    $accountBill->currency = isset($new_bill['currency'])?$new_bill['currency']:'ddc';
                    $accountBill->client_ip = UtilFunction::get_ip();
                    $accountBill->status = 'succeeded';
                    $accountBill->bill_time = $bill_time;
                    if($accountBill->saveOrFail()){
                        // 操作被转账者余额
                        $userAccount = UserAccountModel::where('user_id',$new_bill['to_user_id'])->first();
                        $userAccount->balance = $userAccount->balance + $amount;
                        $userAccount->saveOrFail();
                        return true;
                    }else{
                        Self::$errmsg = '转账失败';
                        return false;
                    }
                }elseif($type == 'withdrawal'){
                    // 转账及时到账，立即操作余额
                    $userAccount = UserAccountModel::where('user_id',$new_bill['user_id'])->first();
                    $userAccount->balance = $userAccount->balance + $amount;
                    $userAccount->saveOrFail();
                    return true;
                }else{
                    return true;
                }
            }else{
                Self::$errmsg = 'bill订单记录失败';
                return false;
            }
        }else{
            Self::$errmsg = '数据传输出错';
            return false;
        }
    }

    public static function update_bill($order_no,$status){
        $accountBill = AccountBillModel::where('order_no',$order_no)->first();
        if ($accountBill) {
            $accountBill->status = $status;
            $accountBill->saveOrFail();
            return true;
        }else{
            return false;
        }
    }
}
